home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / msdos / lynx / source / doslynx / src / turlview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-25  |  22.2 KB  |  723 lines

  1. //      Copyright (c) 1994, University of Kansas, All Rights Reserved
  2. //
  3. //      Class:          TURLView
  4. //      Include File:   turlview.h
  5. //      Purpose:        Provide a view for an HTML document.
  6. //      Remarks/Portability/Dependencies/Restrictions:
  7. //              These functions in effect take the place of the original
  8. //              gridtext functions and provide a multiple document interface
  9. //              since each view will have its own rendered copy of the
  10. //              original HTML image.
  11. //              All functions are here in the same file since all will be
  12. //              called at once.  No need to split up to help overlay manager.
  13. //              The collection TNSCp_lines is used to hold the offset of
  14. //              all inserted lines in the collection.
  15. //      Revision History:
  16. //              02-15-94        created
  17. //              02-18-94        Possible cause for heap corruption adjusted,
  18. //                              incorrect pointer addition.
  19. //                              This only corrected rendered output, heap
  20. //                              corruption still occuring.
  21. //              02-18-94        Changed appendCharacter to accept a
  22. //                              character instead of an signed short int.
  23. //                              Changes split_line to reset the line
  24. //                              split value each time it is called.
  25. //                              No more corrupt heaps it seems.
  26. //              02-18-94        Experiencing crashes after a large number
  27. //                              of lines are processed, no apparent reason.
  28. //                              Optimizing the code, it is very slow....
  29. //              02-21-94        Beginning to see increase in speed due to
  30. //                              minimizing the number of function calls made.
  31. //                              Crashes resulting due to large number of
  32. //                              lines seem to be avoided by increasing the
  33. //                              delta argument in the TNSCollection
  34. //                              constructor (see TURLView constructor).
  35. //              02-22-94        Added member to class, B_avoidinfinite, to
  36. //                              avoid infinite loops in the Double font and
  37. //                              appendCharacter.
  38. //        02-25-94    Modified to work with no HText styles,
  39. //                anchors, or paragraphs in memory.
  40. //                Always assuming that a style is active for
  41. //                speed.
  42. #define Uses_TProgram
  43. #define Uses_TKeys
  44. #include"turlview.h"
  45. #include"tcapture.h"
  46. #include"trace.h"
  47. #include<string.h>
  48.  
  49. extern "C"      {
  50. #include"htfont.h"
  51. };
  52.  
  53. void TURLView::FormatHTML()     {
  54. //      Purpose:        Format the HTML image file produced in gridtext.cpp
  55. //                      into a rendered document fit for display in a view.
  56. //      Arguments:      void
  57. //      Return Value:   void
  58. //      Remarks/Portability/Dependencies/Restrictions:
  59. //              Using indexOf on the HText paragraph collection is fatal
  60. //              for some reason.  Using the member of TextAttribute to find
  61. //              the index.
  62. //      Revision History:
  63. //              02-15-94        created
  64. //        02-25-94    modified so will not read HText image file
  65. //                with anchors, sytles, paragraphs in memory.
  66. //        04-06-94    Modified to compensate for WWW not calling
  67. //                HText_endAppend.
  68. #ifndef RELEASE
  69.     trace("Entering FormatHTML.");
  70. #endif // RELEASE
  71.     //    In certain cases, the WWW library does not call
  72.     //    HText_endAppend.  Do this for them.  We can tell if the image
  73.     //    file still exists.
  74.     if(HTp_HyperDoc->fsp_image != NULL)    {
  75. #ifndef RELEASE
  76.         trace("WWW did not call HText_endAppend.  Doing so now.");
  77. #endif // RELEASE
  78.         ::HText_endAppend(HTp_HyperDoc);
  79.     }
  80.  
  81.     //      Open the HTML image file for reading.
  82.     fsp_image = new fstream(HTp_HyperDoc->TTNp_fspname->
  83.         getName(), ios::in | ios::nocreate | ios::binary);
  84.     if(fsp_image == NULL)   {
  85.         doslynxmessage("Unable to open HText image file " <<
  86.             HTp_HyperDoc->TTNp_fspname->getName());
  87.         B_valid = False;
  88.         return;
  89.     }
  90.  
  91.     //      Open the view's temporary rendered file for writing.
  92.     fsp_temp = new fstream(TTNp_temp->getName(), ios::out | ios::trunc |
  93.         ios::binary);
  94.     if(fsp_temp == NULL)    {
  95.         doslynxmessage("Unable to open HTML rendering file " <<
  96.             TTNp_temp->getName());
  97.         //      Close the HTML image file.
  98.         fsp_image->close();
  99.         delete(fsp_image);
  100.         B_valid = False;
  101.         return;
  102.     }
  103.  
  104.     //      Allocate the two lines with the appropriate screen size and
  105.     //      a safety buffer.
  106.     L_last = (Line *)new char[sizeof(Line) + size.x + 80];
  107.     L_new = (Line *)new char[sizeof(Line) + size.x + 80];
  108.  
  109.     if(L_last == NULL || L_new == NULL)     {
  110.         doslynxmessage("Unable to allocate enough memory to create.");
  111.         //      Close the files.
  112.         fsp_image->close();
  113.         fsp_temp->close();
  114.         delete(fsp_image);
  115.         delete(fsp_temp);
  116.         B_valid = False;
  117.         if(L_last != NULL)      {
  118.             delete[](L_last);
  119.         }
  120.         if(L_new != NULL)       {
  121.             delete[](L_new);
  122.         }
  123.         return;
  124.     }
  125.     L_last->ssi_indent = 0;
  126.     L_last->ssi_length = 0;
  127.  
  128.     //      We are in a new paragraph and can't split anywhere.
  129.     B_line_1 = True;
  130.     ssi_splitAt = 0;
  131.  
  132.     //      Right now, there are no limits to the view.
  133.     limit.y = limit.x = 0;
  134.  
  135.     //      Set member to avoid infinite loop in appendcharacter and
  136.     //      the double font.
  137.     B_avoidinfinite = False;
  138.  
  139.     //    There have been no spaces, but start out if so.
  140.     B_lastSpace = True;
  141.     //    Right now we will collapse spaces.
  142.     B_collapseSpaces = True;
  143.  
  144.     //    No current style
  145.     HTSp_style = NULL;
  146.  
  147.     //    If there were anchors skipped, report it.
  148.     if(usi_skipped != 0U)    {
  149.         doslynxmessage(usi_skipped << " anchors not created due to "
  150.             "memory limitations.");
  151.         usi_skipped = 0U;
  152.     }
  153.  
  154.     //      Go through the HTML image file, calling the appropriate
  155.     //      rendering functions for the temporary rendered file.
  156.     char c_append;
  157.     unsigned short int usi_checkEsc = 0;
  158.     signed long int sli_tellg = fsp_image->tellg();
  159.     while(fsp_image->eof() == 0)    {
  160.         //      Get a character and act upon it.
  161.         //      Update where we are in the file.
  162.         c_append = fsp_image->get();
  163.         sli_tellg++;
  164.         if(c_append == EOF || fsp_image->bad() != 0)    {
  165.             break;
  166.         }
  167.         //    Check for embedded characters.
  168.         else if(c_append == c_Embedded)    {
  169.             //    Is an embedded character, get the next one
  170.             //    that tells us what type of embed it is.
  171.             c_append = fsp_image->get();
  172.             sli_tellg++;
  173.             if(c_append == EOF || fsp_image->bad() != 0)    {
  174.                 break;
  175.             }
  176.             //      Check for styles.
  177.             else if(c_append == c_SetStyle)    {
  178.  
  179.                 auto HTStyle *HTSp_nextStyle;
  180.  
  181.                 //    Changing the current style.
  182.                 //    Get the style pointer from the file.
  183.                 fsp_image->read((char *)(&HTSp_nextStyle),
  184.                     sizeof(HTStyle *));
  185.                 sli_tellg += sizeof(HTStyle *);
  186.                 if(fsp_image->gcount() != sizeof(HTStyle *) ||
  187.                     fsp_image->bad() != 0)    {
  188.                     break;
  189.                 }
  190.  
  191.                 //    If there was a previous style, insert
  192.                 //    blank lines.
  193.                 if(HTSp_style != NULL)    {
  194.                     blank_lines(max(HTSp_style->
  195.                         spaceAfter,
  196.                         HTSp_nextStyle->spaceBefore));
  197.                 }
  198.  
  199.                 //    Change to the current style.
  200.                 HTSp_style = HTSp_nextStyle;
  201.  
  202.                 //    Set wether or not to collapse spaces.
  203.                 //    Will do so whenever style is not
  204.                 //    preformatted or an example.
  205.                 if(HTSp_style != NULL)    {
  206. #ifndef RELEASE
  207.                     trace("Current style is now " <<
  208.                         HTSp_style->name);
  209. #endif // RELEASE
  210.                     if(!strcmp(HTSp_style->name,
  211.                         "Preformatted") ||
  212.                         !strcmp(HTSp_style->name,
  213.                         "Example"))    {
  214.                         B_collapseSpaces = False;
  215.                     }
  216.                     else    {
  217.                         B_collapseSpaces = True;
  218.                     }
  219.                 }
  220.             }
  221.             //    Check for paragraph.
  222.             else if(c_append == c_AppendParagraph)    {
  223.  
  224.                 //    Assume we have a style regardless.
  225.                 blank_lines(max(HTSp_style->spaceAfter,
  226.                     HTSp_style->spaceBefore));
  227.             }
  228.             //    Check for beginning an anchor.
  229.             else if(c_append == c_BeginAnchor)    {
  230.                 auto HTChildAnchor *HTCAp_newAnchor;
  231.  
  232.                 //    Read the value of the pointer from
  233.                 //    file.
  234.                 fsp_image->read((char *)(&HTCAp_newAnchor),
  235.                     sizeof(HTChildAnchor *));
  236.                 sli_tellg += sizeof(HTChildAnchor *);
  237.                 if(fsp_image->gcount() != sizeof(
  238.                     HTChildAnchor *) ||
  239.                     fsp_image->bad() != 0)    {
  240.                     break;
  241.                 }
  242.  
  243.                 //    Begin the anchor in the view.
  244.                 beginAnchor(HTCAp_newAnchor);
  245.             }
  246.             //    Check for ending an anchor.
  247.             else if(c_append == c_EndAnchor)    {
  248.                 //    Simply call end anchor.
  249.                 endAnchor();
  250.             }
  251.         }
  252.         //    Otherwise, should be an appendable character.
  253.         else    {
  254.             appendCharacter(c_append);
  255.         }
  256.  
  257.         //      Every 1k of read information, check to see if
  258.         //      user is trying to interrupt.
  259.         if(usi_checkEsc++ > 1024U)     {
  260.             //      Reset usi_checkEsc
  261.             usi_checkEsc = 0U;
  262.  
  263.             //    Check if safe to coninue formatting due to
  264.             //    memory limitations.  The last ??? chunks of
  265.             //    mem will cause this to break.
  266.             if(really_safe_pool[Stop_Rendering] == NULL)    {
  267.                 doslynxmessage("Unable to display full "
  268.                     "document due to memory limitations.");
  269.                 break;
  270.             }
  271.  
  272.             auto TEvent TE;
  273.  
  274.             //      Get any events in the application.
  275.             //      Calls this to also call idle.
  276.             TProgram::application->getEvent(TE);
  277.  
  278.             //      Interrupt on ESC key.
  279.             if(TE.what & evKeyDown) {
  280.                 if(TE.keyDown.keyCode == kbEsc) {
  281.                     doslynxmessage("Interrupting the "
  282.                         "format process.");
  283.                     doslynxmessage("Display will not "
  284.                         "represent the full "
  285.                         "document.");
  286.                     //      Clear the event.
  287.                     TProgram::application->clearEvent(TE);
  288.                     break;
  289.                 }
  290.             }
  291.  
  292.             //      Print a message if other events occured.
  293.             if(TE.what != evNothing && !(TE.what & evMouseMove)
  294.                 && !(TE.what & evMouseUp))      {
  295.                 doslynxmessage("Formatting.... press ESC to "
  296.                     "interrupt.");
  297.             }
  298.  
  299.             //      Clear the event.
  300.             TProgram::application->clearEvent(TE);
  301.         }
  302.     }
  303.  
  304.     if(fsp_image->bad() != 0)    {
  305.         doslynxmessage("Error while reading HText image file.");
  306.         doslynxmessage("Displaying rendering as is.");
  307.     }
  308.  
  309.     //      Flush and release the lines.
  310.     split_line(0);
  311.     delete[]((char *)L_last);
  312.     delete[]((char *)L_new);
  313.  
  314.     //      Close the files.
  315.     fsp_image->close();
  316.     delete(fsp_image);
  317.     fsp_temp->close();
  318.     delete(fsp_temp);
  319.  
  320.     //      Adjust the selected anchor to now select the anchor in
  321.     //      the rendered file.
  322.     if(HTCAp_2BSelected != NULL)        {
  323.         adjustSelected();
  324.     }
  325.  
  326.     //      Tell the view what it's new bounds are.
  327.     //      This will set the scroll bar values.
  328.     setLimit(limit.x, limit.y);
  329.  
  330. #ifndef RELEASE
  331.     trace("FormatHTML returning.");
  332. #endif // RELEASE
  333. }
  334.  
  335. void TURLView::blank_lines(signed short int ssi_blanks) {
  336. //      Purpose:        Insert a number of blank lines into the rendered
  337. //                      image.
  338. //      Arguments:      ssi_blanks      The number of blank lines to insert.
  339. //      Return Value:   void
  340. //      Remarks/Portability/Dependencies/Restrictions:
  341. //              Will not count the number of previous blank lines before
  342. //              insertion.
  343. //      Revision History:
  344. //              02-16-94        created
  345.  
  346.     //      Insert the appropriate number of blanks.
  347.     //    Always atleast split one line.
  348.     do    {
  349.         split_line(0);
  350.     }
  351.     while(--ssi_blanks > 0);
  352.  
  353.     B_line_1 = True;
  354. }
  355.  
  356. void TURLView::appendCharacter(char c_append)   {
  357. //      Purpose:        Append a character to the output stream.
  358. //      Arguments:      c_append        The character to append.
  359. //      Return Value:   void
  360. //      Remarks/Portability/Dependencies/Restrictions:
  361. //              Assumes that any functions changing the actual last line
  362. //              in the rendered image will update the last line member.
  363. //      Revision History:
  364. //              02-16-94        created
  365. //        03-16-94    Modified to collapse spaces ' ' around all
  366. //                types of whitespace.  For prettier output.
  367. //                Care should be taken to not call this
  368. //                function using spaces to align or indent
  369. //                text, or the formatting will be collapsed.
  370.  
  371.     //    Check to see if we should ignore a space.
  372.     if(c_append == ' ')    {
  373.         //    Ignore it if need be.
  374.         if(B_lastSpace == True && B_collapseSpaces == True)    {
  375.             return;
  376.         }
  377.  
  378.         //    Set for future condensing.
  379.         B_lastSpace = True;
  380.  
  381.         //    Can split the line here.
  382.         ssi_splitAt = L_last->ssi_length;
  383.     }
  384.     else    {
  385.         //    Set so next time we know we have no spaces collapsed.
  386.         B_lastSpace = False;
  387.     }
  388.  
  389.     //      Determine the current indention of the line, if we have
  390.     //      style.
  391.     auto signed short int ssi_indent = 0;
  392.     if(B_line_1 == True)    {
  393.         ssi_indent = HTSp_style->indent1st;
  394.     }
  395.     else    {
  396.         ssi_indent = HTSp_style->leftIndent;
  397.     }
  398.  
  399.     //      Check for new lines.
  400.     //    Set whitespace here.
  401.     if(c_append == '\n')    {
  402.         //    Considered a space so that following spaces are
  403.         //    collapsed.
  404.         B_lastSpace = True;
  405.         split_line(0);
  406.         B_line_1 = True;
  407.         return;
  408.     }
  409.     //      Check for tabs.
  410.     //    If so, consider whitespace.
  411.     else if(c_append == '\t')       {
  412.         //    Considered a space so that we collapse more spaces.
  413.         B_lastSpace = True;
  414.         //      The tab table.
  415.         HTTabStop *HTTSp;
  416.         //      Where to tab to.
  417.         int i_target;
  418.         //      Where we are.
  419.         int i_here = L_last->ssi_length + L_last->ssi_indent
  420.             + ssi_indent;
  421.  
  422.         //      If we have a tab table.
  423.         if(HTSp_style->tabs != NULL) {
  424.             //      Loop through the tab table until
  425.             //      a tab will put the cursor past our
  426.             //      current postion.
  427.             for(HTTSp = HTSp_style->tabs; HTTSp->position <=
  428.                 i_here; HTTSp++)
  429.             {
  430.                 //      No tab specified.
  431.                 if(HTTSp->position == 0)        {
  432.                     split_line(0);
  433.                     return;
  434.                 }
  435.             }
  436.             i_target = HTTSp->position;
  437.         }
  438.         //      No tab table, if in line 1 of a paragraph,
  439.         //      use the leftIndent.
  440.         else if(B_line_1 == True)       {
  441.             //      If already beyond the left indent.
  442.             if(i_here >= HTSp_style->leftIndent)     {
  443.                 split_line(0);
  444.                 return;
  445.             }
  446.             else    {
  447.                 i_target = HTSp_style->leftIndent;
  448.             }
  449.         }
  450.         //      No tab table, not in line 1, use default mod 8
  451.         else    {
  452. #ifdef TABS8
  453.             i_target = (L_last->ssi_indent + L_last->ssi_length +
  454.                 8) % 8 + HTSp_style->leftIndent;
  455. #else
  456.             // Just split the line.
  457.             split_line(0);
  458. #endif // TABS8
  459.             return;
  460.         }
  461.  
  462.         //      If we are past the right margin.
  463.         if(i_target > size.x - HTSp_style->rightIndent)    {
  464.             split_line(0);
  465.             return;
  466.         }
  467.         //      Otherwise, indent the tab.
  468.         else    {
  469.             //      We can split the line here.
  470.             ssi_splitAt = L_last->ssi_length;
  471.             //      If there is nothing in the line, just
  472.             //      increase the indentation.
  473.             if(L_last->ssi_length == 0)     {
  474.                 L_last->ssi_indent += i_target - i_here;
  475.             }
  476.             //      Otherwise, space out.
  477.             else    {
  478.                 for(; i_here < i_target; i_here++)      {
  479.                     *((char *)L_last + sizeof(Line) +
  480.                         L_last->ssi_length) = ' ';
  481.                     L_last->ssi_length++;
  482.                 }
  483.             }
  484.             return;
  485.         }
  486.     }
  487.  
  488.     //      Check if beyond the screen width.
  489.     if(ssi_indent + L_last->ssi_indent + L_last->ssi_length + HTSp_style->
  490.         rightIndent >= size.x)
  491.     {
  492.         if(HTSp_style->wordWrap != 0)        {
  493.             split_line(ssi_splitAt);
  494.             //      We can ignore a space causing a split
  495.             if(c_append == ' ')     {
  496.                 return;
  497.             }
  498.         }
  499.         else    {
  500.             split_line(0);
  501.         }
  502.     }
  503.  
  504.     //      The font of the sytle.
  505.     HTFont HTF = HTSp_style->font;
  506.  
  507.     //      Convert NBS to a space.
  508.     //    Do not consider as whitespace.
  509.     if(c_append == HT_NON_BREAK_SPACE)      {
  510.         c_append = ' ';
  511.     }
  512.     //      Convert the character according to font.
  513.     else if(HTF & HT_CAPITALS)      {
  514.         c_append = toupper(c_append);
  515.     }
  516.  
  517.     //      Add the character to the line.
  518.     *((char *)L_last + sizeof(Line) + L_last->ssi_length) = c_append;
  519.     L_last->ssi_length++;
  520.  
  521.     //      On the double font, do again with a NBS
  522.     if(HTF & HT_DOUBLE)     {
  523.         //      Failsafe to not go infinitly recursive.
  524.         if(B_avoidinfinite == False)    {
  525.             B_avoidinfinite = True;
  526.         }
  527.         else    {
  528.             B_avoidinfinite = False;
  529.         }
  530.  
  531.         if(B_avoidinfinite == True)     {
  532.             appendCharacter(HT_NON_BREAK_SPACE);
  533.         }
  534.     }
  535. }
  536.  
  537. void TURLView::split_line(signed short int ssi_split)   {
  538. //      Purpose:        Split a line at the required offset.
  539. //      Arguments:      ssi_split       Where to split the line.
  540. //                                      If 0, no split, just a new line.
  541. //      Return Value:   void
  542. //      Remarks/Portability/Dependencies/Restrictions:
  543. //      Revision History:
  544. //              02-16-94        created
  545. //              02-22-98        Modified to use nothing but a TNSCollection
  546. //                              to keep track of line offsets into the
  547. //                              rendered file.  No memory other than the
  548. //                              collection is allocated.
  549.  
  550.     //      Reset where last line will be split.
  551.     ssi_splitAt = 0;
  552.  
  553.     //      Fill the members with pertinent data for the new line.
  554.     L_new->ssi_indent = L_new->ssi_length = 0;
  555.  
  556.     //      Split at required point, skip if not needed
  557.     if(ssi_split != 0 && L_last->ssi_length != 0)   {
  558.         //      End the line.
  559.         *((char *)L_last + sizeof(Line) + L_last->ssi_length) =
  560.             '\0';
  561.         //      Skip any space at the split point.
  562.         char *cp;
  563.         for(cp = (char *)L_last + sizeof(Line) + ssi_split; *cp !=
  564.             '\0'; cp++)     {
  565.             if(*cp != ' ')  {
  566.                 break;
  567.             }
  568.         }
  569.         //      Copy the remaining information into the new line and
  570.         //      set the members.
  571.         strcpy(((char *)L_new + sizeof(Line)), cp);
  572.         L_new->ssi_length = strlen(((char *)L_new + sizeof(Line)));
  573.         L_last->ssi_length = ssi_split;
  574.     }
  575.  
  576.     //    Take off any trailing spaces.
  577.     while(L_last->ssi_length != 0 && *((char *)L_last + sizeof(Line) +
  578.         L_last->ssi_length) == ' ' - 1)    {
  579.         L_last->ssi_length--;
  580.     }
  581.  
  582.     //      End the line.
  583.     if(L_last->ssi_length != 0)     {
  584.         *((char *)L_last + sizeof(Line) + L_last->ssi_length) =
  585.             '\0';
  586.     }
  587.  
  588.     //      Align the line according to style.
  589.     auto int i_indent = (B_line_1 == True) ? HTSp_style->indent1st :
  590.         HTSp_style->leftIndent;
  591.     auto int i_spare = size.x - HTSp_style->rightIndent +
  592.         HTSp_style->leftIndent - L_last->ssi_length;
  593.  
  594.     switch(HTSp_style->alignment)        {
  595.     case HT_CENTER:
  596.         L_last->ssi_indent += i_indent + i_spare / 2;
  597.         break;
  598.     case HT_RIGHT:
  599.         L_last->ssi_indent += i_indent + i_spare;
  600.         break;
  601.     default:
  602.         L_last->ssi_indent += i_indent;
  603.         break;
  604.     }
  605.  
  606.     //      We are no longer in the first line of a paragraph unless
  607.     //      the calling function sets this otherwise.
  608.     B_line_1 = False;
  609.  
  610.     //      Set the line collection to know where the offset of the
  611.     //      line to be serialized is.  Using only an offset to track.
  612.     //      Using the offset as a void * to track.
  613.     TNSCp_lines->insert((void *)(fsp_temp->tellp()));
  614.  
  615.     //      Write the line to the rendered image file.
  616.     fsp_temp->write((const char *)L_last, sizeof(Line) + L_last->
  617.         ssi_length);
  618.     //    Check for error in write, if so, must unfortunately exit.
  619.     if(fsp_temp->bad() != 0)    {
  620.         doslynxmessage("Error in creating rendered image.");
  621.  
  622.         //    Attemp closing the files.
  623.         fsp_temp->close();
  624.         fsp_image->close();
  625.  
  626.         //    Cause the application to quit.
  627.         TEvent TE_quit;
  628.         TE_quit.what = evMessage;
  629.         TE_quit.message.command = cmQuit;
  630.         TProgram::application->handleEvent(TE_quit);
  631.     }
  632.  
  633.     //      Increment the total number of lines and maximum width.
  634.     limit.y++;
  635.     limit.x = max(limit.x, L_last->ssi_length + L_last->ssi_indent);
  636.  
  637.     //      We have a new last line.
  638.     Line *L_temp = L_last;
  639.     L_last = L_new;
  640.     L_new = L_temp;
  641. }
  642.  
  643. void TURLView::beginAnchor(const HTChildAnchor *HTCAp_anchor)    {
  644. //      Purpose:        Mark the beginning of an anchor in the rendered image.
  645. //      Arguments:      HTCAp_anchor    The child anchor to begin.
  646. //      Return Value:   void
  647. //      Remarks/Portability/Dependencies/Restrictions:
  648. //              Creates a new anchor entry with offsets in the rendered file
  649. //              pointing to the corresponding current anchor.
  650. //      Revision History:
  651. //              02-17-94        created
  652.  
  653.     //      Create a new anchor.
  654.     TextAttribute *TAp_newanc = new TextAttribute(HTCAp_anchor);
  655.     if(TAp_newanc == NULL)  {
  656.         doslynxmessage("Unable to allocate space for new anchor.");
  657.         B_valid = False;
  658.         return;
  659.     }
  660.  
  661.     //      Get the offset of the last line and it's offset by length
  662.     //      and structure size.
  663.     signed long int sli_where = fsp_temp->tellp() + (signed long int)
  664.         (L_last->ssi_length + sizeof(Line));
  665.  
  666.     //      Set the beginning offset in the rendering.
  667.     TAp_newanc->Begin(sli_where);
  668.  
  669.     //      Insert the anchor into the anchor collection.
  670.     TNSCp_anchors->insert((void *)TAp_newanc);
  671. }
  672.  
  673. void TURLView::endAnchor()      {
  674. //      Purpose:        End an anchor in the rendered image.
  675. //      Arguments:      void
  676. //      Return Value:   void
  677. //      Remarks/Portability/Dependencies/Restrictions:
  678. //              Ends the last anchor in the collection at the current
  679. //              length of the last line in the offset of the rendering.
  680. //      Revision History:
  681. //              02-17-94        created
  682.  
  683.     //      Get the last anchor.  Assume there is always one.
  684.     TextAttribute *TAp_anclast = (TextAttribute *)(TNSCp_anchors->at(
  685.         TNSCp_anchors->getCount() - 1));
  686.  
  687.     //      Get the offset of the last line and it's offset by length
  688.     //      and structure size.
  689.     signed long int sli_where = fsp_temp->tellp() + (signed long int)
  690.         (L_last->ssi_length + sizeof(Line));
  691.  
  692.     //      Set the ending offset in the rendering.
  693.     TAp_anclast->End(sli_where);
  694. }
  695.  
  696. void TURLView::adjustSelected() {
  697. //      Purpose:        The selected anchor originally points to the anchor
  698. //                      owned by HText.  Convert the pointer of that anchor
  699. //                      to the corresponding anchor owned by the view.
  700. //      Arguments:      void
  701. //      Return Value:   void
  702. //      Remarks/Portability/Dependencies/Restrictions:
  703. //      Revision History:
  704. //              02-17-94        created
  705.  
  706. #ifndef RELEASE
  707.     trace("Adjusting the selected anchor.");
  708. #endif // RELEASE
  709.  
  710.     //      Find the corresponding anchor.
  711.     //      Assume that a match will always be found.
  712.     TextAttribute *TAp_same;
  713.     for(TAp_same = (TextAttribute *)(TNSCp_anchors->at(0));
  714.         TAp_same->HTCAp_anchor != HTCAp_2BSelected;
  715.         TAp_same = (TextAttribute *)(TNSCp_anchors->at(TNSCp_anchors
  716.         ->indexOf((void *)TAp_same) + 1)))      {
  717.         //      Null body
  718.     }
  719.  
  720.     //      Set the selected anchor.
  721.     TAp_selected = TAp_same;
  722. }
  723.